#pragma once

#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/core.hxx>
#include <odb/nullable.hxx>
#include <string>

#pragma db object
class Student {
   public:
    Student() {}
    Student(const unsigned long student_number, const std::string& name,
            unsigned int age, unsigned long class_id)
        : student_number_(student_number),
          name_(name),
          age_(age),
          class_id_(class_id) {}

    void student_number(const unsigned long student_number) {
        student_number_ = student_number;
    }
    unsigned long student_number() { return student_number_; }

    void name(const std::string& name) { name_ = name; }
    std::string& name() { return name_; }

    void age(const unsigned int age) { age_ = age; }
    odb::nullable<unsigned int> age() { return age_; }

    void class_id(const unsigned long class_id) { class_id_ = class_id; }
    unsigned long class_id() { return class_id_; }

   private:
    friend class odb::access;
#pragma db id auto
    unsigned long id_;
#pragma db unique
    unsigned long student_number_;
    std::string name_;
    odb::nullable<unsigned int> age_;
#pragma db index
    unsigned long class_id_;
};

#pragma db object
class Classes {
   public:
    Classes() {}
    Classes(const std::string& class_name) : class_name_(class_name) {}

    void class_name(const std::string& class_name) { class_name_ = class_name; }
    std::string class_name() { return class_name_; }

   private:
    friend class odb::access;
#pragma db id auto
    unsigned long id_;
#pragma db unique
    std::string class_name_;
};

// 只查询学生姓名
#pragma db view object(Student) query((?))
struct AllName {
    std::string name_;
};

// 查询所有的学生信息，并显示班级名称
// 因为需要用到多表联查，将 Student表 和 Class表
// 连接到一起，创建视图，条件为：Student::class_id_ == Class::id_
// 为了完成查询，需要加上自定义查询 query - ? 是外部调用时传入的过滤条件
#pragma db view object(Student) \ 
                object(Classes = classes : Student::class_id_ == classes::id_) \ 
                query((?))
struct ClassStudent {
#pragma db column(Student::id_)
    unsigned long id_;
#pragma db column(Student::student_number_)
    unsigned long student_number_;
#pragma db column(Student::name_)
    std::string name_;
#pragma db column(Student::age_)
    odb::nullable<unsigned int> age_;
#pragma db column(classes::class_name_)
    std::string class_name_;
};

//odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time student.hxx